package com.voyager.tools.jira;

import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import com.voyager.tools.jira.pojo.At;
import com.voyager.tools.jira.pojo.DingTalkMarkdownMessage;
import com.voyager.tools.jira.pojo.Item;
import com.voyager.tools.jira.pojo.JiraPostData;
import com.voyager.tools.jira.pojo.Markdown;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;

/**
 * @author voyager.fu
 * @date 2020/11/19
 */
@Slf4j
public class JiraWebHookUtil {

    private static final String DING_TALK_ROBOT_URL = "https://oapi.dingtalk.com/robot/send" +
            "?access_token=xxxxxxxxxxxx";
    private static final String JIRA_BASE_URL = "http://xxx.xxx.xxx.xxx:38080/browse/";
    private static RestTemplate restTemplate = new RestTemplate();

    public static boolean hook(JiraPostData postData){
        try {
            if(postData != null){
                if(StringUtils.equals(postData.getWebhookEvent(), "jira:issue_updated")){
                    //更新事件
                    List<Item> items = postData.getChangelog().getItems();
                    String toUserId = Strings.EMPTY;
                    String fromUserId = Strings.EMPTY;
                    for(Item item : items){
                        if(StringUtils.equals(item.getField(), "assignee")){
                            toUserId = item.getTo();
                            fromUserId = item.getFrom();
                            break;
                        }
                    }
                    if(StringUtils.isNotBlank(toUserId) && StringUtils.isNotBlank(fromUserId)){
                        String toMobile = getUserMobile(toUserId);
                        String fromMobile = getUserMobile(fromUserId);
                        if(StringUtils.isNotBlank(toMobile) && StringUtils.isNotBlank(fromMobile)){
                            String issueKey = postData.getIssue().getKey();
                            String issueSummary = postData.getIssue().getFields().getSummary();
                            DingTalkMarkdownMessage msg = new DingTalkMarkdownMessage();
                            msg.setMsgtype("markdown");
                            Markdown markdown = new Markdown();
                            markdown.setTitle(postData.getIssue().getKey());
                            markdown.setText("### @" + fromMobile + " 【转移任务给】@" + toMobile
                                    + "\n>任务编号：[" + issueKey + "](" + JIRA_BASE_URL + issueKey + ")"
                                    + "  \n任务标题：" + issueSummary);
                            msg.setMarkdown(markdown);
                            At at = new At();
                            at.setAtMobiles(Arrays.asList(toMobile, fromMobile));
                            msg.setAt(at);
                            return sendMsgToDingTalk(JSONObject.toJSONString(msg));
                        }
                    }
                }else if(StringUtils.equals(postData.getWebhookEvent(), "jira:issue_created")){
                    //创建事件
                    String fromUserId = postData.getUser().getKey();
                    String toUserId = postData.getIssue().getFields().getAssignee().getKey();
                    if(StringUtils.isNotBlank(toUserId) && StringUtils.isNotBlank(fromUserId)){
                        String toMobile = getUserMobile(toUserId);
                        String fromMobile = getUserMobile(fromUserId);
                        if(StringUtils.isNotBlank(toMobile) && StringUtils.isNotBlank(fromMobile)){
                            String issueKey = postData.getIssue().getKey();
                            String issueSummary = postData.getIssue().getFields().getSummary();
                            DingTalkMarkdownMessage msg = new DingTalkMarkdownMessage();
                            msg.setMsgtype("markdown");
                            Markdown markdown = new Markdown();
                            markdown.setTitle(postData.getIssue().getKey());
                            markdown.setText("### @" + fromMobile + " 【指派任务给】@" + toMobile
                                    + "\n>任务编号：[" + issueKey + "](" + JIRA_BASE_URL + issueKey + ")"
                                    + "  \n任务标题：" + issueSummary);
                            msg.setMarkdown(markdown);
                            At at = new At();
                            at.setAtMobiles(Arrays.asList(toMobile, fromMobile));
                            msg.setAt(at);
                            return sendMsgToDingTalk(JSONObject.toJSONString(msg));
                        }
                    }
                }
            }

        }catch (Exception e) {
            log.error("触发JIRA网络钩子失败", e);
        }
        return false;
    }

    private static boolean sendMsgToDingTalk(String msg){
        JSONObject postData = JSONObject.parseObject(msg);
        JSONObject result = restTemplate.postForObject(DING_TALK_ROBOT_URL, postData, JSONObject.class);
        if(result != null
                && result.getIntValue("errcode") == 0
                && StringUtils.equals(result.getString("errmsg"), "ok")){
            return true;
        }
        return false;
    }

    private static String getUserMobile(String userId){
        String mobile = Strings.EMPTY;

        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://xxxxxx:389");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "cn=xxx,dc=xxx,dc=xxx,dc=com");
        env.put(Context.SECURITY_CREDENTIALS, "xxxxxxxx");
        DirContext ctx = null;
        try{
            ctx = new InitialDirContext(env);
        }catch(Exception e){
            log.error("连接LDAP失败", e);
        }

        // 设置过滤条件
        String filter = "(&(objectClass=top)(objectClass=inetOrgPerson)(cn=" + userId + "))";
        // 限制要查询的字段内容
        String[] attrPersonArray = {"cn", "mobile"};
        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        // 设置将被返回的Attribute
        searchControls.setReturningAttributes(attrPersonArray);
        // 三个参数分别为：
        // 上下文；
        // 要搜索的属性，如果为空或 null，则返回目标上下文中的所有对象；
        // 控制搜索的搜索控件，如果为 null，则使用默认的搜索控件
        try {
            NamingEnumeration<SearchResult> answer = ctx.search(
                    "ou=People,dc=xxx,dc=xxx,dc=com", filter, searchControls);
            // 输出查到的数据
            while (answer.hasMore()) {
                SearchResult result = answer.next();
                Attribute attr = result.getAttributes().get("mobile");
                mobile = attr.get().toString();
                break;
            }
        }catch (Exception e){
            log.error("查询LDAP用户信息失败", e);
        }
        return mobile;
    }

}
